package ext;

import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

/**
 * @author 北京八维博大科技 薛建新
 * @date 2022年11月8日 10:38:04
 * @Copyright 北京八维博大科技
 */
//https://www.cnblogs.com/markLogZhu/p/12497258.html
//https://juejin.cn/post/7144167544692146183#heading-11
public final class SecondInitializer
		implements ApplicationContextInitializer<AnnotationConfigServletWebServerApplicationContext> {

	// 总共4字节，固定为0xCAFEBABE
	private static final byte[] CLASS_MAGIC = ByteBuffer.allocate(Integer.BYTES).putInt(0xCAFEBABE).array();
	private static final String CLASS_START = ".jar!/";
	private static final String CLASS = ".class";
	private static final boolean DEBUG = true;

	@Override
	public void initialize(AnnotationConfigServletWebServerApplicationContext applicationContext) {
		final var rl=new PathMatchingResourcePatternResolver() {
			protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, URL rootDirURL,
					String subPattern) throws IOException {
				Set<Resource> rs = super.doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern);
				Iterator<Resource> it = rs.iterator();
				Set<Resource> newSouce = new HashSet<>();
				while (it.hasNext()) {
					Resource r = it.next();
					if (r.getFilename().endsWith(CLASS)) {
						byte[] content = r.getInputStream().readAllBytes();
						if (isClass(content)) {
							r = new ByteArrayResource(content);
						} else {
							if (DEBUG) {
								System.out.println(r.getURL() + "------" + r.getClass() + "," + r.getClass() + ",path="
										+ r.getURL().getPath() + ",File=" + r.getURL().getFile());
							}
							String className = r.getURL().getFile();
							int startIndex = className.lastIndexOf(CLASS_START);
							if (startIndex >= 0) {// jar包中的
								className = className.substring(startIndex + CLASS_START.length());
							} else {
								// 非jar包中的暂时还不用处理
							}
							if (DEBUG) {
								System.out.println("className->" + className);
							}
							r = new ByteArrayResource(getClassLoader().getResourceAsStream(className).readAllBytes());
						}
						newSouce.add(r);
						it.remove();
					}
				}
				rs.addAll(newSouce);
				return rs;
			}

		};
		applicationContext.setResourceLoader(rl);
		System.out.println("##########run Initializer###############");
	}

	// 判断是否class
	private static boolean isClass(byte[] content) {
		boolean isClass = Arrays.equals(content, 0, 4, CLASS_MAGIC, 0, 4);
		return isClass;
	}

}
